package utils;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

/**
 * Session Filter，用来控制请求 其中参数logonPages，登陆页面 includePages，哪些页面需要过滤.
 * redirectPath，没有登陆时的转向页面 userAttributeName Session中“用户”对象的标示名
 * disabletestfilter，过滤器是否有效。
 * @author spring
 * @since 2006.1.12
 */
public class SessionFilter implements Filter {
    /**
     * 判断字符串里是否包含指定的字符模式.
     * @param container 要判断的字符串 .
     * @param regx 匹配的字符模式 .
     * @return boolean .
     */
    private static boolean isContains(String container, String[] regx) {
        boolean result = false;

        for (String item : regx) {
            if (container.indexOf(item) != -1) {
                return true;
            }
        }
        return result;
    }

    /**
     * sevelet Filter Config.
     */
    private FilterConfig config = null;

    /**
     * 本过滤器是否失效.
     */
    private boolean disableFilter = false;

    /**
     * 用来判断Sessoin 是否登陆过.
     */
    private String userAttributeName = null;

    /**
     * 系统的登陆页面.
     */
    private String[] loginPages = null;

    /**
     * 没有登陆时的重定向页面(一般同登陆页面).
     */
    private String redirectPath = null;

    /**
     * 设置完FilterConfig之后的逻辑.
     */
    public void afterSetFilterConfig() {
        disableFilter = "Y".equalsIgnoreCase(config
                .getInitParameter("disabletestfilter"));
        userAttributeName = config.getInitParameter("userAttributeName");
        String loginStrings = config.getInitParameter("loginPages");
        loginPages = loginStrings.split(";");
        redirectPath = config.getInitParameter("redirectPath");
    }

    /**
     * 进行request filter.
     * @param request http request
     * @param response http response
     * @param chain filer chain
     * @throws IOException io exception
     * @throws ServletException servlet exception
     */
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpreq = (HttpServletRequest) request;
        HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper(
                (HttpServletResponse) response);

        if (disableFilter) {
            chain.doFilter(request, response);
            return;
        }
        if (isContains(httpreq.getRequestURI(), loginPages)) {
            chain.doFilter(request, response);
            return;
        }
        Object user = httpreq.getSession().getAttribute(userAttributeName);
        if (user == null) {

            wrapper.sendRedirect(redirectPath);

        } else {
            chain.doFilter(request, response);
        }
    }

    /**
     * 初始化.
     * @param filterConfig servlet filter config
     * @throws ServletException sevlet exception when error
     */
    public void init(FilterConfig filterConfig) throws ServletException {
        this.config = filterConfig;
        this.afterSetFilterConfig();
    }

    /**
     * destroy.
     */
    public void destroy() {
        // nothing to do

    }
}